package com.github.ilioili.justdoit.components.fragment;

import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.CardView;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

import com.github.ilioili.justdoit.R;
import com.github.ilioili.justdoit.common.config.EventConstants;
import com.github.ilioili.justdoit.model.dao.RecordDao;
import com.github.ilioili.justdoit.model.dao.ScheduleEventDao;
import com.github.ilioili.justdoit.model.pojo.EventRecord;
import com.github.ilioili.justdoit.model.pojo.ScheduleEvent;
import com.github.ilioili.justdoit.util.CompatUtil;
import com.github.ilioili.justdoit.util.DateRepeatUtil;
import com.github.ilioili.justdoit.util.DateUtil;
import com.github.ilioili.justdoit.util.sql.SqlCallback;
import com.github.ilioili.justdoit.widget.MonthView;
import com.github.ilioili.justdoit.widget.SatelliteView;
import com.taihe.template.base.BaseFragment;
import com.taihe.template.base.injection.Id;
import com.taihe.template.base.injection.Layout;
import com.taihe.template.base.util.SizeUtil;

import java.util.Calendar;
import java.util.HashMap;
import java.util.List;

/**
 * Created by hantuo on 16/5/10.
 */
@Layout(R.layout.fragment_month_view)
public class MonthViewFragment extends BaseFragment {

    private static final String BUNDLE_KEY_YEAR = "year";
    private static final String BUNDLE_KEY_MONTH = "month";
    private HashMap<String, EventRecord> recordPojos = new HashMap<>();
    private ScheduleEvent scheduleEvent;
    private int year;
    private int month;
    private float cardViewElevation;
    private SatelliteView satelliteView;
    private int clickYear;
    private int clickMonth;
    private int clickDay;
    private View clickView;

    private static final String BUNDLE_KEY_HABIT = "habit";


    public static MonthViewFragment newInstance(ScheduleEvent scheduleEvent, int year, int month) {
        Bundle bundle = new Bundle();
        bundle.putSerializable(BUNDLE_KEY_HABIT, scheduleEvent);
        bundle.putInt(BUNDLE_KEY_YEAR, year);
        bundle.putInt(BUNDLE_KEY_MONTH, month);
        MonthViewFragment fragment = new MonthViewFragment();
        fragment.setArguments(bundle);
        return fragment;
    }

    @Id(R.id.monthview)
    private MonthView monthView;

    private View.OnClickListener onClickNotMatchedDay = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Snackbar.make(v, "重复设置里未配置该日期", Snackbar.LENGTH_SHORT).show();
        }
    };

    private View.OnClickListener onClickBeforeStartTime = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Snackbar.make(v, "过去日子的就让它过去吧", Snackbar.LENGTH_SHORT).show();
        }
    };

    private View.OnClickListener onClickAfterToday = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Snackbar.make(v, "未来的还是留给未来吧", Snackbar.LENGTH_SHORT).show();
        }
    };

    private void invokeDataChangedListener() {
        if (null != onDataChangedListener) onDataChangedListener.onDataChanged();
    }

    private void setUpSatelliteViews() {
        satelliteView = (SatelliteView) LayoutInflater.from(getContext()).inflate(R.layout.satellite_layout, null);
        satelliteView.findViewById(R.id.s_amost_complete).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                satelliteView.collapse();
                EventRecord eventRecord = new EventRecord(clickYear, clickMonth, clickDay, scheduleEvent.id);
                eventRecord.state = EventConstants.STATE_AMOST_COMPLETE;
                RecordDao.replace(eventRecord);
                recordPojos.put(getKey(clickMonth, clickDay), eventRecord);
                setItem(clickView, clickYear, clickMonth, clickDay);
                clickView.setVisibility(View.GONE);
                clickView.post(new Runnable() {
                    @Override
                    public void run() {
                        clickView.setVisibility(View.VISIBLE);
                    }
                });
                invokeDataChangedListener();

            }
        });
        satelliteView.findViewById(R.id.s_complete).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                satelliteView.collapse();
                EventRecord eventRecord = new EventRecord(clickYear, clickMonth, clickDay, scheduleEvent.id);
                eventRecord.state = EventConstants.STATE_COMPLETE;
                RecordDao.replace(eventRecord);
                recordPojos.put(getKey(clickMonth, clickDay), eventRecord);
                setItem(clickView, clickYear, clickMonth, clickDay);
                clickView.invalidate();
                invokeDataChangedListener();
            }
        });
        satelliteView.findViewById(R.id.s_forget).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                satelliteView.collapse();
                EventRecord eventRecord = new EventRecord(clickYear, clickMonth, clickDay, scheduleEvent.id);
                eventRecord.state = EventConstants.STATE_FORGET;
                RecordDao.delete(eventRecord);
                recordPojos.remove(getKey(clickMonth, clickDay));
                setItem(clickView, clickYear, clickMonth, clickDay);
                clickView.invalidate();
                invokeDataChangedListener();
            }
        });
        satelliteView.findViewById(R.id.s_give_up).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                satelliteView.collapse();
                EventRecord eventRecord = new EventRecord(clickYear, clickMonth, clickDay, scheduleEvent.id);
                eventRecord.state = EventConstants.STATE_LAZY;
                RecordDao.replace(eventRecord);
                recordPojos.put(getKey(clickMonth, clickDay), eventRecord);
                setItem(clickView, clickYear, clickMonth, clickDay);
                clickView.invalidate();
                clickView.setVisibility(View.GONE);
                clickView.post(new Runnable() {
                    @Override
                    public void run() {
                        clickView.setVisibility(View.VISIBLE);
                    }
                });
                invokeDataChangedListener();
            }
        });
        satelliteView.findViewById(R.id.s_half).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                satelliteView.collapse();
                EventRecord eventRecord = new EventRecord(clickYear, clickMonth, clickDay, scheduleEvent.id);
                eventRecord.state = EventConstants.STATE_FAIL_IN_THE_MIDDLE;
                RecordDao.replace(eventRecord);
                recordPojos.put(getKey(clickMonth, clickDay), eventRecord);
                setItem(clickView, clickYear, clickMonth, clickDay);
                clickView.invalidate();
                invokeDataChangedListener();
            }
        });
        satelliteView.findViewById(R.id.s_make_up).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                satelliteView.collapse();
                EventRecord eventRecord = new EventRecord(clickYear, clickMonth, clickDay, scheduleEvent.id);
                eventRecord.state = EventConstants.STATE_MAKE_UP;
                RecordDao.replace(eventRecord);
                recordPojos.put(getKey(clickMonth, clickDay), eventRecord);
                setItem(clickView, clickYear, clickMonth, clickDay);
                clickView.invalidate();
                invokeDataChangedListener();
            }
        });
        satelliteView.findViewById(R.id.s_too_busy).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                satelliteView.collapse();
                EventRecord eventRecord = new EventRecord(clickYear, clickMonth, clickDay, scheduleEvent.id);
                eventRecord.state = EventConstants.STATE_TOO_BUSY;
                RecordDao.replace(eventRecord);
                recordPojos.put(getKey(clickMonth, clickDay), eventRecord);
                setItem(clickView, clickYear, clickMonth, clickDay);
                clickView.invalidate();
                invokeDataChangedListener();
            }
        });
    }


    @Override
    protected void init(View rootView) {
        super.init(rootView);
        cardViewElevation = Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP ? SizeUtil.dpToPx(3, getContext()) : SizeUtil.dpToPx(3, getContext());
        setUpSatelliteViews();
        scheduleEvent = (ScheduleEvent) getArguments().getSerializable(BUNDLE_KEY_HABIT);
        year = getArguments().getInt(BUNDLE_KEY_YEAR);
        month = getArguments().getInt(BUNDLE_KEY_MONTH);
        monthView.setAdapter(new MonthView.Adapter() {
            @Override
            public View getView(View view, final int year, final int month, final int day) {
                if (null == view) {
                    view = LayoutInflater.from(getActivity()).inflate(R.layout.day_cell, monthView, false);
                }
                setItem(view, year, month, day);
                return view;
            }


        });
        monthView.setMonth(year, month);
        loadData();
    }

    private void setItem(View view, final int year, final int month, final int day) {
        final TextView textView;
        final CardView cardView;
        cardView = (CardView) view.findViewById(R.id.cardView);
        textView = (TextView) view.findViewById(R.id.textView);
        textView.setText(day + "");
        long startDayStartTime = DateUtil.clearHmsm(scheduleEvent.startTime);
        final long curDayStartTime = DateUtil.getDayStartTime(year, month, day);
        boolean match = curDayStartTime >= startDayStartTime && curDayStartTime < DateUtil.getTodayEndTime();
        String key = getKey(month, day);
        if (match) {
            final EventRecord eventRecord = recordPojos.get(key);
            cardView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    clickDay = day;
                    clickMonth = month;
                    clickYear = year;
                    clickView = (View) v.getParent();
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTimeInMillis(curDayStartTime);
                    int row = monthView.getRow(clickView);
                    switch (calendar.get(Calendar.DAY_OF_WEEK)) {
                        case Calendar.SUNDAY:
                            if (row < 4) {
                                satelliteView.expand(v, SizeUtil.dpToPx(120, getContext()), 180, 360);
                            } else if (row == 4) {
                                satelliteView.expand(v, SizeUtil.dpToPx(180, getContext()), 180, 290);
                            } else {
                                satelliteView.expand(v, SizeUtil.dpToPx(220, getContext()), 180, 270);
                            }
                            break;
                        case Calendar.MONDAY:
                            if (row < 4) {
                                satelliteView.expand(v, SizeUtil.dpToPx(120, getContext()), 0, 180);
                            } else if (row == 4) {
                                satelliteView.expand(v, SizeUtil.dpToPx(180, getContext()), 70, 180);
                            } else {
                                satelliteView.expand(v, SizeUtil.dpToPx(220, getContext()), 90, 180);
                            }
                            break;
                        case Calendar.TUESDAY:
                            if (row < 4) {
                                satelliteView.expand(v, SizeUtil.dpToPx(100, getContext()), -20, 200);
                            } else if (row == 4) {
                                satelliteView.expand(v, SizeUtil.dpToPx(150, getContext()), 60, 200);
                            } else {
                                satelliteView.expand(v, SizeUtil.dpToPx(190, getContext()), 90, 190);
                            }
                            break;
                        case Calendar.SATURDAY:
                            if (row < 4) {
                                satelliteView.expand(v, SizeUtil.dpToPx(100, getContext()), 160, 380);
                            } else if (row == 4) {
                                satelliteView.expand(v, SizeUtil.dpToPx(150, getContext()), 160, 300);
                            }
                            break;
                        default:
                            satelliteView.expand(v, SizeUtil.dpToPx(80, getContext()), 0, 360);

                    }
                }
            });
            if (DateRepeatUtil.matchTheDay(scheduleEvent.repeatFlag, curDayStartTime)) {
                cardView.setCardElevation(cardViewElevation);
                if (eventRecord == null) {
                    cardView.setCardBackgroundColor(CompatUtil.getColor(getContext(), R.color.state_forget));
                    textView.setTextColor(CompatUtil.getColor(getContext(), R.color.font_cyan));
                } else {
                    textView.setTextColor(Color.WHITE);
                    switch (eventRecord.state) {
                        case EventConstants.STATE_COMPLETE:
                            cardView.setCardBackgroundColor(CompatUtil.getColor(getContext(), R.color.state_complete));
                            break;
                        case EventConstants.STATE_AMOST_COMPLETE:
                            cardView.setCardBackgroundColor(CompatUtil.getColor(getContext(), R.color.state_amost_complete));
                            break;
                        case EventConstants.STATE_FAIL_IN_THE_MIDDLE:
                            cardView.setCardBackgroundColor(CompatUtil.getColor(getContext(), R.color.state_fail_in_half));
                            break;
                        case EventConstants.STATE_FORGET:
                            cardView.setCardBackgroundColor(CompatUtil.getColor(getContext(), R.color.state_forget));
                            textView.setTextColor(CompatUtil.getColor(getContext(), R.color.font_cyan));
                            break;
                        case EventConstants.STATE_LAZY:
                            cardView.setCardBackgroundColor(CompatUtil.getColor(getContext(), R.color.state_lazy));
                            break;
                        case EventConstants.STATE_TOO_BUSY:
                            cardView.setCardBackgroundColor(CompatUtil.getColor(getContext(), R.color.state_busy));
                            break;
                        case EventConstants.STATE_MAKE_UP:
                            cardView.setCardBackgroundColor(CompatUtil.getColor(getContext(), R.color.state_make_up));
                            break;
                    }
                }
            } else {
                clearItem(textView, cardView, curDayStartTime);
            }
            cardView.setTag(eventRecord);
        } else {
            clearItem(textView, cardView, curDayStartTime);
        }
    }


    private void clearItem(TextView textView, CardView cardView, long curDayStartTime) {

        if (curDayStartTime < scheduleEvent.startTime) {
            cardView.setOnClickListener(onClickBeforeStartTime);
        } else if (curDayStartTime >= DateUtil.getTodayEndTime()) {
            cardView.setOnClickListener(onClickAfterToday);
        } else {
            cardView.setOnClickListener(onClickNotMatchedDay);
        }
        textView.setTextColor(CompatUtil.getColor(getContext(), R.color.font_cyan));
        cardView.setCardElevation(0);
//        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP){
//            cardView.setCardBackgroundColor(Color.TRANSPARENT);
//        }
    }

    public void freshData() {
        loadData();
    }

    private void loadData() {
        recordPojos.clear();
        ScheduleEvent event = ScheduleEventDao.getById(scheduleEvent.id);
        if (null != event) {
            scheduleEvent = event;
            RecordDao.getList(year, month, scheduleEvent.id, new SqlCallback<List<EventRecord>>() {
                @Override
                public void onSucess(List<EventRecord> eventRecords) {
                    for (EventRecord eventRecord : eventRecords) {
                        recordPojos.put(getKey(eventRecord.month, eventRecord.day), eventRecord);
                    }
                    monthView.freshView();
                }
            });
        }

    }

    private String getKey(int month, int day) {
        return "" + month + day;
    }

    public void setOnDataChangedListener(OnDataChangedListener listener) {
        onDataChangedListener = listener;
    }


    private OnDataChangedListener onDataChangedListener;

    public interface OnDataChangedListener {
        void onDataChanged();
    }
}
